/*
输入一个整数 n：棋盘大小

输出 n 个整数，第 i 个数表示第 i 行皇后的位置 
*/
#include <bits/stdc++.h>

#define MAXN 5000007

using namespace std;

// rand()范围太小，要超大规模随机数，所以要这个，注意这个是unsigned long long int，所以要强制类型转换成int
typedef std::subtract_with_carry_engine<std::uint_fast64_t, 48, 5, 12> ranlux48_base;


int n;                          // n表示皇后数量
int queen[MAXN];                // queen[i]表示第i行的皇后在第几列
int attack[MAXN];               // 表示哪些皇后是可以相互攻击的
int diagonalNegative[2 * MAXN + 7];// 正反对角线的冲突数量
int diagonalPositive[2 * MAXN + 7];
int collisions;                 // 总冲突数
bool columnUsed[MAXN] = {false};// 记录某一列是不是已经放了东西了

//想在第row行第col列放皇后，检查这个皇后是不是和以前放的有冲突
bool check(int row, int col) {
    int negativeIndex = row + col;
    int positiveIndex = row - col;
    return (diagonalNegative[negativeIndex] == 0 && diagonalPositive[n - 1 + positiveIndex] == 0);
}

//随机生成一个棋盘布局
void generateARadomPermutation() {
    ranlux48_base rb;
    const int THRESHOLD = (int) (5.0 / 12.0 * n);
    int generatedQueenNumber = 0;
    memset(diagonalPositive, 0, 2 * n * sizeof(int));
    memset(diagonalNegative, 0, 2 * n * sizeof(int));

    while (generatedQueenNumber < n) {
        int col;
        do {
            col = (int) (rb() % n);
        } while (columnUsed[col]);
        if (generatedQueenNumber < THRESHOLD)
            if (check(generatedQueenNumber, col) == false) { continue; }

        queen[generatedQueenNumber] = col;
        columnUsed[col] = true;
        int negativeIndex = generatedQueenNumber + col;
        ++diagonalNegative[negativeIndex];
        int positiveIndex = generatedQueenNumber - col;
        ++diagonalPositive[n - 1 + positiveIndex];
        ++generatedQueenNumber;
    }
}

//交换皇后
void performSwap(int i, int j) {
    --diagonalNegative[i + queen[i]];
    --diagonalNegative[j + queen[j]];
    --diagonalPositive[n - 1 + i - queen[i]];
    --diagonalPositive[n - 1 + j - queen[j]];
    int tmp = queen[i];
    queen[i] = queen[j];
    queen[j] = tmp;
    ++diagonalNegative[i + queen[i]];
    ++diagonalNegative[j + queen[j]];
    ++diagonalPositive[n - 1 + i - queen[i]];
    ++diagonalPositive[n - 1 + j - queen[j]];
}

//检查交换给定的两个皇后会不会减少冲突数
int swapWillReduceCollisions(int i, int j) {
    int delta = 0;
    delta -= diagonalNegative[i + queen[i]] - 1;
    delta -= diagonalNegative[j + queen[j]] - 1;
    if (i + queen[i] == j + queen[j]) {
        ++delta;
    }
    delta -= diagonalPositive[n - 1 + i - queen[i]] - 1;
    delta -= diagonalPositive[n - 1 + j - queen[j]] - 1;
    if (i - queen[i] == j - queen[j]) {
        ++delta;
    }
    delta += diagonalNegative[i + queen[j]];
    delta += diagonalNegative[j + queen[i]];
    if (i + queen[j] == j + queen[i]) {
        ++delta;
    }
    delta += diagonalPositive[n - 1 + i - queen[j]];
    delta += diagonalPositive[n - 1 + j - queen[i]];
    if (i - queen[j] == j - queen[i]) {
        ++delta;
    }
    return delta;
}

//计算冲突
int computeCollisions() {
    int collisions = 0;
    for (int i = 0; i < 2 * n - 1; ++i) {
        collisions += diagonalNegative[i] * (diagonalNegative[i] - 1) / 2;
        collisions += diagonalPositive[i] * (diagonalPositive[i] - 1) / 2;
    }
    return collisions;
}

//获得能够相互攻击的皇后的编号
int computeAttacks() {
    memset(attack, 0, n * sizeof(int));
    int numberOfAttacks = 0;
    for (int i = 0; i < n; ++i) {
        int negativeIndex = i + queen[i];
        int positiveIndex = i - queen[i];
        if (diagonalNegative[negativeIndex] > 1 || diagonalPositive[n - 1 + positiveIndex] > 1) {
            attack[numberOfAttacks] = i;
            ++numberOfAttacks;
        }
    }
    return numberOfAttacks;
}
int main() {
    ranlux48_base rb;
    cin >> n;
    // C1是为了计算一个阈值，当冲突小于阈值的时候重新计算attack数组，这里的常系数定义参考了Rok sosic和Jun Gu的QS2算法的定义，C1取0.53
    const double C1 = 0.45;
    // C2是为了最大化N较小的时候的运行速度，对较大的N没有影响，这里的常系数定义参考了Rok sosic和Jun Gu的QS2算法的定义，C2取32
    const double C2 = 32;
    do {
        generateARadomPermutation();
        collisions = computeCollisions();
        int limit = (int) (C1 * collisions);
        int numberOfAttacks = computeAttacks();
        int loopCount = 0;
        do {
            if (collisions == 0) {
                break;
            }
            // 只遍历能够相互攻击的皇后
            for (int k = 0; k < numberOfAttacks; ++k) {
                // 找到一个具有攻击性的皇后，再随机地找一个和自己不一样的皇后
                int i = attack[k];
                int j;
                do {
                    j = (int) (rb() % n);
                } while (i == j);
                int delta;
                // 如果交换后的冲突是减小的，执行交换
                if ((delta = swapWillReduceCollisions(i, j)) < 0) {
                    // 更新冲突数，并执行交换
                    collisions += delta;
                    performSwap(i, j);
                    // 冲突数为0，找到解，输出，冲突数小于阈值，重新计算阈值和attack数组
                    if (collisions == 0) {
                        break;
                    }

                    if (collisions < limit) {
                        limit = (int) (C1 * collisions);
                        numberOfAttacks = computeAttacks();
                    }
                }
            }
            loopCount += numberOfAttacks;
        } while (loopCount <= C2 * n);
    } while (collisions != 0);
    
    for(int i=0;i<n;i++) cout<<queen[i]<<endl;

    return 0;
}